home *** CD-ROM | disk | FTP | other *** search
-
- The following excerpt hails from "Chapter 3" of the "IRIX 5.1 IDO
- Release Notes," and is followed by "Appendix A" which is the
- Dynamic Shared Objects--DSOs--Frequently Asked Questions list.
-
-
-
- ______________________________________________________________________________
-
-
- "Dynamic Linking and DSOs"
-
- In previous versions of IRIX (pre-5.0), executables were only "statically
- linked". This means that all references must be resolved (and their
- addresses fixed) at link time (by LD(1)). In this release, such
- programs, although they might use pre-5.0 shared libraries (which are
- referred to now as "static shared libraries") are referred to as "non-
- shared". They are produced by compiling and linking with the
- "-non_shared" option. The code so created is *not* position-independent
- (PIC).
-
- In 5.0 and later IRIX releases, in addition to being statically linked by
- LD(1), programs are, by default, compiled as PIC code and "dynamically
- linked", that is, part of the program may be relocated dynamically at run
- time. There are two types of dynamically linked objects:
-
- * The executable itself. This consists of your main program and
- PIC code extracted from all archive libraries linked with it.
- Code within the executable is not relocated at run time, but
- some of its references will be. The executable is linked
- "-call_shared".
-
- * External sharable dynamically linked objects called "dynamic
- shared objects" (DSOs), which are not part of the executable
- itself. DSOs and their references may be dynamically relocated
- at run time. DSOs are linked "-shared". DSOs by convention
- have the extension ".so". A DSO may be shared by several users
- and/or programs, possibly at different addresses.
-
- You cannot mix "non-shared" objects and PIC objects in the same
- executable.
-
- On this and future release, "static shared libraries" are supported only
- for the use of existing (pre-5.0) executables that reference them. You
- can neither create new static shared libraries nor link new code with
- existing static shared libraries.
-
- PIC code satisfies references indirectly by using a Global Offset Table
- (GOT), which allows code to be relocated simply by updating the GOT.
- Your executable has one GOT, and each DSO it uses has one GOT.
-
- When a dynamically linked executable is started, the run-time linker,
- RLD(1), is invoked to prepare the program for execution. This
- preparation involves:
-
- * Filling in certain global values.
-
- * Relocating any dynamic shared objects (DSOs) that your program
- references.
-
- * Resolving data symbols in DSOs that were unresolved at static
- link time by LD(1).
-
- With very few exceptions, all executable objects in this release are
- dynamically linked. A new component, the run-time linker /lib/rld, and
- all standard DSOs (file extension ".so") are necessary for programs to
- execute.
-
- More information about these types of objects appears in Appendix A,
- "Frequently Asked Questions about DSOs," (include below) and in the
- "IRIX Programming Guide".
-
-
- "Object File Format Changes"
-
- The compiler tools and the link editor now produce ELF format objects and
- executables by default. DSO is supported only in ELF executables and
- object files. COFF files are run on IRIX 5.0 with the IRIX 4.0.5 ABI,
- and ELF files are run with the IRIX 5.0 ABI; hence, the linker refuses
- to mix (pre-5.0) COFF and ELF objects.
-
- Two new header files are associated with ELF objects:
- /usr/include/elf_abi.h contains definitions that are generic to all
- implementations. /usr/include/elf_mips.h contains definitions specific
- to the MIPS architecture. See the "System V Application Binary
- Interface" and "System V Application Binary Interface MIPS Processor
- Supplement", published by UNIX System Laboratories, for details.
-
- A new object file reader, ELFDUMP(1), is associated with ELF format
- files. This program is known on some other SVR4-compliant systems as
- "dump".
- ______________________________________________________________________________
-
-
-
- =============================================
- Frequently Asked Questions about DSOs
- =============================================
-
-
-
-
- This list hails from the IRIX 5.2 DSO man page, begins near the top of
- page 5, and constitues the remaining 15+ pages of this manual page.
-
-
- FREQUENTLY ASKED QUESTIONS
- List of Questions:
-
- 1) What is DSO?
- 2) How do dynamic shared objects compare with shared libraries?
- 3) How do I maintain binary compatibility between versions of
- dso's?"
-
- 4) Under which versions of the OS can I use DSO?
- 5) What object-file format does DSO use?
- 6) How do I install the tools so I can use DSO on my system?
- 7) How do I build an executable that uses a shared object?
- 8) How do I build an executable that doesn't use shared
- linking?"
-
- 9) How do I tell if an executable will use dynamic linking?
- 10) How do I build a shared object?
- 11) Where does the system look for shared objects at runtime?
- 12) What is Quickstart?
- 13) What is the so_locations file?
- 14) What directives can be put in a so_locations file?
- 15) What is /usr/lib/so_locations?
- 16) If I don't have a valid so_locations, can I generate one from
- all the .so's in, say, /usr/lib?"
-
- 17) How expensive is it (at runtime) to NOT use the
- -update_registry option?"
-
- 18) How and when will Quickstart be used?
- 19) What about run-time loading under user control?
- 20) What benefits will I get from DSO?
- 21) What costs are associated with DSO?
- 22) What is the -KPIC option?
- 23) Must main programs which want to use DSO's use -KPIC for
- compilation?"
-
- 24) How do I change my assembly language sources to use -KPIC?
- 25) Can I mix IRIX 4 static shared libraries with DSO's?
- 26) What options do I have when building a shared object?
- 27) What pitfalls should I know about which are associated with
- DSO?"
-
- Page 5 Release 5.2
-
- DSO(5) Silicon Graphics DSO(5)
-
- 28) What should I do about a GOT overflow?
- 29) How are multiple versions of DSO's supported?
- 30) Where can I find more documentation on DSO?
- 1) What is DSO?
- DSO stands for Dynamic Shared Objects. DSO provides a capability similar
- to static shared libraries under Cypress and earlier versions of the
- IRIX, e.g., it gives applications the ability to share the text of
- heavily used libraries, which need not be included in the executable
- file. However DSO has two important distinctions from static shared
- objects.
-
- 2) How do dynamic shared objects compare with shared libraries?
- First, a dynamic shared object contains only position-independent code,
- so that it may be mapped into the virtual address space of different
- processes at different addresses and still be shared. Second, dynamic
- shared objects, and indeed the executable itself are mapped in by a
- runtime loader, rld, which resides in memory in the same address space as
- the executable. This gives the system the ability to change the binding
- of symbols during executions, at the request of the executing program.
- This capability should prove useful across a large segment of
- applications.
-
- 3) How do I maintain binary compatibility between versions of dso's?
- As long as the shared objects maintain the same exported symbols, or
- perhaps add new symbols without removing any or changing semantics, and
- don't change exported structures, they will be binary compatible.
- Ordering of symbols, routines, are irrelevant, as global data, etc. We
- are working on a system called Delta-C++ which should allow you to add to
- exported classes without recompiling.
-
- 4) Under which versions of the OS can I use DSO?
- DSO is available under IRIX versions 5.0 and later. Programs built with
- DSO will not work on earlier version of IRIX.
-
- 5) Which object-file format does DSO use?
- DSO uses the ELF object file format, as defined in the SVR4 ABI. ELF
- objects cannot be run under IRIX 4.0.5 or earlier.
-
- 6) How do I install the tools so I can use DSO on my system?
- IRIX 5.0 and later releases all support/use DSO's. In order to compile
- and build shared objects you will need to have the Developer's option
- installed.
-
- 7) How do I build an executable that uses a shared object?
- cc myfile.c -lmine
-
- This will link you with libmine.so and also with libc.so.1, if either are
- available. If no libmine.so is available, but there is a libmine.a, the
- libmine.a will be used along with libc.so.1, and you will still get
- dynamic linking. If you wish to be explicit, add the -call_shared flag
- to the cc line:
-
- Page 6 Release 5.2
-
- DSO(5) Silicon Graphics DSO(5)
-
- cc -call_shared myfile.c -lmine
-
- 8) How do I build an executable that doesn't use shared linking?
- Use the -non_shared flag:
-
- cc -non_shared myfile.c -lmine
-
- 9) How do I tell if an executable will use dynamic linking?
- elfdump -o shows you the ELF program header. This contains all the
- information necessary for exec and rld to run the program/shared object.
- Only a.outs which use dynamic linking will have a PHDR, INTERP, or
- DYNAMIC entry.
-
- Here's an example, and a more detailed description of this stuff.
-
- % elfdump -o /bin/cat
-
- ***PROGRAM HEADER***
- Type Offset Vaddr Paddr Filesz Memsz Align RWX
- PHDR 0x00000034 0x00400034 0x00400034 0x000000c0 0x00000000 0x00000004 r--
- INTERP 0x00000100 0x00400100 0x00400100 0x00000009 0x00000009 0x00000004 r--
- REGINFO 0x00000110 0x00400110 0x00400110 0x00000018 0x00000018 0x00000004 r--
- DYNAMIC 0x00000150 0x00400150 0x00400150 0x00000a70 0x00000a70 0x00000010 r--
- LOAD 0x00000000 0x00400000 0x00400000 0x00003000 0x00003000 0x00001000 r-x
- LOAD 0x00003000 0x10000000 0x10000000 0x00001000 0x00001290 0x00010000 rwx
-
- Each line is an entry in the program header, and refers to a "segment" of
- the file.
-
- PHDR points to the program header itself within the file. Only
- executables which use dynamic linking will have this field.
-
- INTERP
- points to a place in the file where the name of the interpreter
- required for this program is to be found. For any ABI-conforming
- object, this name will be "/usr/lib/libc.so.1".
-
- REGINFO
- points to a place in the file where information about register setup
- can be found. Currently this mostly consists of the correct gp
- value for this object.
-
- DYNAMIC
- points to the information in the file which is needed by rld to
- execute it correctly. This information includes the liblist, a
- symbol table, and other information.
-
- LOAD points to segments that are to be mapped into the memory image.
-
- Page 7 Release 5.2
-
- DSO(5) Silicon Graphics DSO(5)
-
- The columns give various information about each segment.
-
- Offset
- is the offset in the file to the beginning of the segment.
-
- Vaddr
- is the virtual address of the beginning of the segment in the memory
- image of the file, ASSUMING that it was mapped as described in the
- LOAD entries
-
- Paddr
- is the same as Vaddr in our implementation.
-
- Filesz
- is the size of the segment in the file.
-
- Memsz
- is the size of the segment in the memory image. When this is larger
- it is assumed to be zero-filled.
-
- Align
- is the alignment required by this section. If an segment is to be
- mapped somewhere into memory other than at Vaddr, the new address
- must be congruent to Vaddr modulo the alignment. In the example
- above, the first segment must always be loaded at a page boundary,
- and the second must always be loaded at a 64K boundary.
-
- RWX specifies the protections r(ead), w(rite), or x(ecute) for the
- segment.
-
- Programs which are linked -non_shared do not have a PHDR, INTERP, or
- DYNAMIC section. Thus elfdump -o is a convenient method to determine if
- a program is linked -non_shared or not.
-
- 10) How do I build a shared object?
- To begin with, build a .o or .a which contains all the routines you want
- to have in your .so (shared object). This can be done with cc -c and ar.
- Then invoke ld with the -shared flag. Normally the extension .so is used
- to designate shared objects.
-
- Here is an example:
-
- cc -c myobj.c
- ld -shared myobj.o -o myobj.so
-
- -or-
-
- <build libmine.a the usual way.>
- ld -shared -all libmine.a -o libmine.so
-
- Page 8 Release 5.2
-
- DSO(5) Silicon Graphics DSO(5)
-
- The -all flag in the second example tells ld to include all the routines
- in the library. This is necessary since there are no undefined
- references (in a main, say) which is the usual way that ld knows to
- include files from an archive.
-
- 11) Where does the system look for shared objects at runtime?
- The search path for shared objects is acquired in the following order:
-
- 1) the path of the shared object if given in the liblist,
-
- 2) in any directories specified via the
- -rpath flag when the executable was built
-
- 3) in any directory specified by the LD_LIBRARY_PATH environment
- variable, if it is defined
-
- 4) in the directories in the default path
- (/usr/lib:/lib:/lib/cc:/usr/lib/cc)
-
- If the _RLD_ROOT environment variable is defined, then its value is
- appended to the front of any path specified by -rpath and the default
- path. _RLD_ROOT itself is also a colon(:) separated list.
-
- See the rld(1) manpage for details.
-
- 12) What is Quickstart?
- Quickstart is an optimization. Using the so_locations file, each shared
- object is pre-relocated by ld, as if it had been loaded at the address in
- the so_locations file. That way, if nothing unusual happens when we
- start up the application, all the shared objects will map at their
- Quickstart addresses, and rld will not need to do a relocation pass over
- them.
-
- If for some reason more than one shared object wishes to map the same
- address, rld will move one of them to an unused address and perform a
- relocation pass to fix up the address references.
-
- If one or more of the shared objects linked against at static link time
- has changed by the time the program executes, rld will need to do extra
- work to ensure that symbols have been resolved to their proper value.
-
- 13) What is the so_locations file?
- In the directory in which you build a shared object, after you've
- actually built one, you will notice a file named so_locations.
-
- It is a registry of shared objects. It maintains the default or
- Quickstart addresses of a group of shared objects which are to cooperate
- by not having their default location overlap with one another. It is
- generated and updated by ld each time it builds a shared object.
-
- Page 9 Release 5.2
-
- DSO(5) Silicon Graphics DSO(5)
-
- 14) What directives can be put in an so_locations file?
- Comment line
- so_name [ :st = { .text | .data | $range } base_addr,padded_size : ] *
-
- where
- so_name full path name (or trailing component) of a
- shared object
- st string identifying start of the segment description
- .text | .data segment types: text or data
- $range limit the range of address that can be used
- base_addr address where the segment starts
- padded_size padded size of the segment
-
- The following directives control the placement of new shared objects:
-
- $text_align_size=<align> padding=<pad-size>
- $data_align_size=<align> padding=<pad-size>
- These two directives specify the alignment and padding
- requirements for text and data segments respectively.
- The size value in so location is calculated based on:
- (section size + padding) aligned to the section align size
- The align values for text and data as well as the padding
- values must be aligned to a bucket size. If not, ld will
- generate a warning message and align these values to bucket
- size.
-
- $start_address=<addr>
- Specifies where to start looking for addresses to put shared
- objects.
-
- $data_after_text=[ 1 | 0 ]
- Instructs the linker to place data immediately after the text
- at specified text and data alignment requirements.
- We set the data_after_text to 0 if the argument of this directive
- is missing.
-
- Also, when building a dso with the -check_registry or -update_registry
- flag, and if there is already an entry corresponding to this dso in the
- so_location file, the linker will try to assign the same addresses for
- text and data. However, if the size of the dso changes and does not fit
- in the specified location any more, the linker will search for another
- spot that fits. If the optional $range comment is given, the linker will
- only place the dso in the specified range of addresses. If there is not
- enough room, an error will be given.
-
- 15) What is /usr/lib/so_locations?
- This file represents the default layout for the system shared objects.
- Developers who build shared objects may find it interesting to consult
- this file, in order to avoid collisions between their shared objects and
- system shared objects. This file is absolutely irrelevant to users who
- merely run programs which use shared objects.
-
- Page 10 Release 5.2
-
- DSO(5) Silicon Graphics DSO(5)
-
- There are two options which are relevant, -update_registry, and <file>
- looks at <file> and builds the current .so at a location which doesn't
- conflict with anything in the file (unless the current one is listed. -
- check_registry does not write to <file>. -update_registry <file> will
- consult <file> as with -check_registry, but will attempt to write an
- entry for the .so being built into <file>. If <file> is not writable, -
- update_registry turns into If <file> is not readable -check_registry and
- -update_registry are ignored.
-
- 16) If I don't have a valid so_locations file, can I generate one from all
- the .so's in, say, /usr/lib?
- There is no convenient method to do so. There is no guarantee that all
- the .so's in /usr/lib have been coordinated so that a consistent
- so_locations file can be made from them. So it is better to get the one
- that a particular release was made with.
-
- 17) How expensive is it (at runtime) NOT to use -update_registry option?
- The costs are all startup costs. It is very difficult to say how much a
- particular executable will suffer since it depends on which shared
- objects the program uses and whether they have been Quickstarted for the
- same address. When there is a conflict between two objects, one will be
- moved, which means that all addresses referring to names in that object
- need to be relocated.
-
- 18) How and when will Quickstart be used?
- Normally, the linker will use Quickstart unless there are unresolved
- symbols at static link time.
-
- In every executable and every shared object is a list of objects which
- were looked at at static link time -- when the object was made. This
- list also contains timestamps and checksums for each of the objects.
- Various levels of extra work are required if the timestamp or checksum
- has changed in the library at run-time.
-
- 19) What about run-time loading under user control?
- We support an interface known as libdl, which allows users to dynamically
- load their own shared objects as needed. The calls are
-
- dlopen() -- open a new shared object and get a "handle" to it.
-
- dlsym() -- find the value of a name defined in an object.
-
- dlclose()-- close a shared object.
-
- dlerror()-- report errors.
-
- sgidladd() -- functions much like dlopen however it exposes
- all symbols to the rest of the program.
-
- Consult the individual manpages for details.
-
- Page 11 Release 5.2
-
- DSO(5) Silicon Graphics DSO(5)
-
- 20) What benefits will I get from DSO?
- Executables linked with shared objects will be smaller since the shared
- objects are not part of the executable file image.
-
- Executables which use a shared object need not be relinked if a shared
- object is changed -- once the updated shared object is installed, the
- executable will pick it up automatically.
-
- Shared libraries are much easier to build, use, and debug than static
- shared libraries.
-
- DSO allows application designers to make more machine-independent
- software. System-dependent routines can be given a uniform interface and
- a shared object which implements that interface can be built for each
- different platform. Then an actual application can be shipped as-is
- ("shrink-wrapped" software) to various platforms and run on them all.
-
- DSO gives applications the ability to change the binding of symbols at
- run time, under user control.
-
- 21) What costs are associated with DSO?
- A shared object incurs two costs, both against performance.
-
- At startup, there will be a startup cost while rld maps in the various
- objects, performs symbol resolution, etc. We believe this cost is small
- compared to the time it takes to contact the X server, for example.
- Quickstart will reduce this time for smaller applications.
-
- A shared object's text must be PIC (position independent code).
- PICification is accomplished by the code generator (ugen) and assembler
- (as), when the -KPIC flag is specified. This is the default However, PIC
- code is necessarily slower. Experiments have indicated that this speed
- reduction is usually less than 5 percent, but can be as much as 15
- percent. depending on the application. PIC code seems to be worst on
- very small leaf routines which access global data.
-
- 22) What is the -KPIC option?
- This flags tells the code generator and assembler to generate PIC
- directly. The result is an object file that can be put into a DSO
- without further modification
-
- cc -KPIC -c foo.c
-
- will give you a PIC object foo.o. Other drivers (cc, pc, f77, and as)
- also accept the -KPIC option. This is the default.
-
- Routines written in assembly languages need to be modified before -KPIC
- can be used. See the question below.
-
- PIC objects generated by using -KPIC must be compiled -G 0.
-
- Page 12 Release 5.2
-
- DSO(5) Silicon Graphics DSO(5)
-
- 23) Must main programs which want to use DSO's use -KPIC for compilation?
- Yes. DSO's use -KPIC so that position-independent code will be
- generated. Main programs are not generally position-independent, but
- must still use the DSO calling convention when calling a routine which is
- defined in a DSO. In particular, this means that a main program must have
- a GOT, and the code which is generated must use it. Therefore, modules
- which will become part of main programs must be compiled -KPIC as well as
- modules which become part of DSO's.
-
- 24) How do I change my assembly language sources to use -KPIC?
- Several new assembler directives are added to support generation of PIC.
- You should also get yourself familiar with the MIPS ABI Supplement and
- the PIC coding model it describes. In addition, files which are to be
- assembled with -KPIC must also be -G 0. This is normally turned on by
- the driver by default.
-
- Note that with the exception of (a) and (d), all other directives
- described below will be ignored when -KPIC is not explicitly specified.
- Also, item (d), ".gpword", will be turned into ".word". The result will
- be a NON-PIC version of the same routine.
-
- a) .option pic2
-
- This directive forces the assembler to mark the output object file "PIC"
- and activates the following directives. It overrides the command line
- argument. Normally, you don't need to specify this directive. Instead,
- you should use the -KPIC or -non_shared flags to toggle between
- generating PIC or non-PIC.
-
- Note that even though -KPIC will be made the default for the high-
- language driver (cc/pc/f77) in future releases, it will *NOT* be the
- default for assembly sources. You will always have to explicitly specify
- -KPIC for compiling .s files.
-
- b) .cpload reg
-
- This directive expands into three instructions that sets the gp register
- to the context pointer value for the current function. The three
- instructions are:
- lui gp,_gp_disp
- addui gp,gp,_gp_disp
- addu gp,gp,reg
-
- _gp_disp is a reserved symbol defined by the linker to be the distance
- between the lui instruction and the context pointer. This directive is
- required at the beginning of each subroutine that uses the gp register.
-
- You must add this directive at the beginning of every procedure, with the
- exception of leaf-procedures that do not access any global variables, and
- procedures that are static (i.e., not marked .globl or .extern).
-
- Page 13 Release 5.2
-
- DSO(5) Silicon Graphics DSO(5)
-
- c) .cprestore offset
-
- This directive causes the assembler to issue
- sw gp,offset(sp)
- at the point where it appears. Additionally, it causes the assembler to
- emit
- lw gp,offset(sp)
- after every jump-and-link (jal) or branch-and-link (bal) operation,
- thereby restoring the gp register after function calls. The programmer
- is responsible for allocating the stack space for the gp. This space
- should be in the saved register area of the stack frame to remain
- consistent with MIPS' calling and debugger conventions.
-
- d) .gpword local-sym
-
- This directive is similar to .word except that the relocation entry for
- local-sym has the R_MIPS_GPREL32 type. After linkage, this results in a
- 32-bit value that is the distance between local-sym and the context
- pointer (i.e. the gp). local-sym must be local. It is currently used
- for PIC switch tables.
-
- e) .cpadd reg
-
- This adds the value of the context pointer (gp) to reg.
-
- EXAMPLES:
- This is a simplified version of the "hello world" program:
- --------------------------------------------------------------
- .option pic2
- .data
- .align 2
- $$5:
- .ascii "hello world\X0A\X00"
- .text
- .align 2
- main:
- .set noreorder
- .cpload $25
- .set reorder
- subu $sp, 40
- sw $31, 36($sp)
- .cprestore 32
- la $4, $$5
- jal printf
- move $2, $0
- lw $31, 36($sp)
- addu $sp, 40
- j $31
- ----------------------------------------------------------------
- The actual instructions generated by the assembler will be:
-
- lui gp,0 #
-
- Page 14 Release 5.2
-
- DSO(5) Silicon Graphics DSO(5)
-
- addiu gp,gp,0 # generated by .cpload
- addu gp,gp,t9 #
- lw a0,0(gp) # gp-relative addressing used
- lw t9,0(gp) # t9 is used for func. call
- addiu sp,sp,-40
- sw ra,36(sp)
- sw gp,32(sp) # from .cprestore
- jalr ra,t9 # jal is changed to jalr
- addiu a0,a0,0
- lw ra,36(sp)
- lw gp,32(sp) # activated by .cprestore
- move v0,zero
- jr ra
- addiu sp,sp,40
- nop
- ----------------------------------------------------------------
-
- NOTE:
-
- The MIPS's ABI required register t9 ($25) be used for indirect function
- call, so .cpload should always use $25. No reorder mode should also be
- used. Also, programmers should make sure that t9 is dead before any
- function call.
-
- If your program uses an indirect jump (jalr), you must also use t9 as the
- jump register.
-
- If you have an unconditional jump to an external label:
- j _cerror
- you have to rewrite it into indirect jump via t9, i.e.:
- la t9,_cerror
- j t9
-
- If you use branch-and-link (bal) instruction, and if the target procedure
- begins with a .cpload, you have to specify an alternate entry point:
-
- foo: .set noreorder # callee
- .cpload $25
- .set reorder
- $$1: ... # alternative entry point
- ...
- j $31 # foo returns
-
- bar: ... # caller
- ...
- bal $$1 # by-pass the .cpload
- ...
-
- This is very important because .cpload assumes register $25 contains the
- address of foo, but in this case $25 is not set up. Note that since both
- foo and bar reside in the same file, they must have the same value for
- $gp. So the .cpload instructions can be and must be bypassed. However,
-
- Page 15 Release 5.2
-
- DSO(5) Silicon Graphics DSO(5)
-
- since foo can still be called from outside, the .cpload is still
- required.
-
- Alternatively, if you don't want to have an alternate entry point, you
- can set up register $25 before the bal:
- la t9,foo
- bal foo
-
- but this will be less efficient.
-
- position-independent jump table (or any table of text addresses).
- Entries of the address table created by .gpword are converted into
- displacement from the context pointer. To get the correct text address,
- .cpadd should be used to add the value of gp back to them. Since the gp
- is updated by the run-time linker, the correct text address can be
- reconstructed regardless of the location of the dso.
-
- 25) Can I mix IRIX 4 static shared libraries with DSO's?
- We do not anticipate ever allowing an a.out to use both static shared
- libraries and dso.
-
- 26) What options do I have when building a shared object?
- If you specify the flag -B dynamic while linking a shared object, symbols
- in the shared object will be resolved differently than the default
- linkage convention. In particular, the runtime linker will always try to
- resolve any symbols referenced in that object to symbols defined in that
- object first, instead of looking for definitions in objects in the order
- specified on the link line.
-
- The effect of this is to make all symbols defined and used in such
- objects non-preemptable. Ordinarily a such symbol definitions could be
- preempted by a definition in an earlier shared object, but when -B
- symbolic is specified, this is not the case.
-
- 27) What pitfalls are associated with DSO?
- Behind most of the surprises that users will get is the fact that linking
- semantics are fundamentally different, but only in a subtle way. Let us
- suppose that your program links with three libraries, libA, libB and
- libC, in that order. Further suppose that both libA and libC define some
- symbol x, but don't use it. Furthermore, let us suppose that libB
- contains a reference to x. Archive linking (the old way) will resolve
- B's reference to x to the definition in C, whereas shared object linking
- will resolve B's reference to x to the definition in A.
-
- Why the difference? With archive linking, when libA is examined, there
- is no outstanding reference to x, hence the definition of x is not
- extracted from the archive. Later when libC is examined, there is a
- reference to x, so it is loaded.
-
- With shared objects, all the constituent object files have been joined
- into one object, so all symbol definitions are always present. The
- resolution rule is simple, take the definition in the object listed
-
- Page 16 Release 5.2
-
- DSO(5) Silicon Graphics DSO(5)
-
- first. Thus the definition in libA is used.
-
- Another sort of surprise is the "runtime dangling reference". It is
- altogether possible to build and link an application with no errors or
- even warnings, only to get a message from rld stating that your program
- has unresolvable symbols.
-
- What's going on? Well, if you build a shared object as part of your
- program, the linker will not normally complain about undefined symbols
- during a link of a shared object. This is because undefined symbols are
- expected during such a build and are perfectly acceptable. But if the
- main program does not use a symbol, it does not get flagged as undefined
- during static linking. Thus the runtime "surprise". You can use the -
- no_unresolved flag to the linker to avoid such surprises.
-
- Now we get to a nasty pitfall which can be avoided by some cleverness in
- building a shared object. If a particular object in an archive has an
- external reference to a data symbol (which it expects to be defined in
- main, libl.a, for example) the linker would not try to resolve that
- external unless the object file in question was actually referenced by
- the main program. Now if that archive is turned into a shared object
- naively, the external data reference must be resolved whenever ANY
- function in the shared object is used, even if no function in the object
- file in question is ever called and no use is made of the external data
- symbol in question.
-
- This can lead to a scenario where a user has a link that worked with the
- archives, but builds a program which gets nuked by the runtime linker
- under the new scheme of things. I believe that it is a very bad idea for
- us to convert libraries. such as libl.a, which contain external data
- symbols, to shared objects naively.
-
- One thing that can be done is to split the archive into several shared
- objects which are placed on the liblist of a "master" shared object.
- Since rld will not by default try to resolve data symbols until the first
- call is made to a particular object we can create the situation where no
- attempt to resolve the offending external data symbol is made until a
- call is made to the object in which it is referenced.
-
- Here's an example of how that works: Let us suppose that
- has_extern_data.o is an object with an undefined external in it which
- resides in the archive libxyz.a Here is how to isolate that external
- data reference:
-
- First make has_extern_data.o into a shared object all its own.
-
- % ar x libxyz.a has_extern_data.o
- % ld -shared has_extern_data.o -o has_extern_data.so
-
- Now, make libxyz.so, excluding has_extern_data.o from being included
- directly, but instead putting it in the liblist of libxyz.so
-
- Page 17 Release 5.2
-
- DSO(5) Silicon Graphics DSO(5)
-
- % ld -shared -all -exclude has_extern_data.o libxyz.a has_extern_data.so -o libxyz.so
-
- 28) What should I do about a GOT overflow?
- By default, addresses are loaded out of the Global Offset Table (GOT)
- using a 16 bit offset from a context pointer. This means that the size
- of the GOT is limited (by default) to 64K bytes, or about 16 K symbols.
- When there are too many symbols referenced by a DSO (or a.out) the linker
- issues the messag "GOT overflows" and will specify an object file which
- references the symbol which is "out of reach".
-
- SGI recommends that when developers encounter this problem, they attempt
- to split the DSO or a.out in question into several smaller DSO's, each of
- which can conform to the GOT size limit. Maximum performance can be
- achieved this way.
-
- However, as an alternative, developers may wish to use the -xgot
- compile-time flag to tell the compiler to issue a different (and slower)
- code sequence uses a 32-bit offset. This will allow the GOT to contain
- up to 1G entries. However, it is critical that every object linked into
- a final DSO or a.out be compiled with -xgot turned on, otherwise code may
- have been generated which will not work with an extended GOT. However,
- files compiled with -xgot may be linked into a DSO or a.out which has a
- GOT that does not exceed the 16K limit and will work correctly, if
- somewhat slower. The GOT size of any shared objects linked is
- irrelevant.
-
- The directory /usr/lib/xgot contains the extended-GOT versions of those
- objects which SGI has built both normally and -xgot. If a system or third
- party archive contains small GOT objects which are needed in an extended
- GOT link, a developer can take the following steps: 1) Look in
- /usr/lib/xgot to see if an extended GOT version exists. 2) Turn the
- archive into its own shared object, thus isolating it from the extended
- GOT binary. 3) contact the archive provider. In a few cases (crt1.o,
- crtn.o, c++init.o, and fixade.o), where the performance issues were
- minimal, the default objects in /usr/lib are in fact built large GOT.
-
- 29) How are multiple versions of DSO's supported?
- IRIX 5.0.1 (Compilers v3.16) and later supports the ability to tag shared
- objects and executables with a version number. This is intended to
- support interface changes. Details are below; items marked (SGI ONLY) do
- not apply to MSIG ABI binaries, but only to binaries generated on IRIX
- without the -abi flag turned on.
-
- Versioning of Shared Objects.
-
- QUICK OVERVIEW
-
- In order for a shared object to be versioned in the future
- the following needs to be done:
-
- * Version strings consist of 3 parts and a dot: The string "sgi",
- a decimal number (the major number), a dot, and a decimal number
-
- Page 18 Release 5.2
-
- DSO(5) Silicon Graphics DSO(5)
-
- (the minor number).
-
- * Add the command -set_version sgi1.0 to the command to build
- the shared object (cc -shared, ld -shared, etc.).
-
- * (Future) Whenever you make a COMPATIBLE change update the minor version
- number (the one after the dot), and add the latest version string
- to colon-separated list of version strings, e.g., -set_version
- sgi1.0:sgi1.1:sgi1.3
-
- * (Future) Whenever you make an INCOMPATIBLE change, update the
- major version number. Pass this as the version list, e.g.,
- -set_version sgi2.0. Change the filename of the OLD shared object
- by adding a dot followed by the previous major number to the filename
- of the shared object. DO NOT CHANGE the soname of the object.
- No change to the file contents are necessary or desirable. Simply
- rename the file.
-
- HOW IT ALL WORKS
-
- * Versioning will only be available for NON-ABI executables.
- The current ABI does not require objects to have versioning, nor
- does it require systems to pay attention to versioning. It does
- allow objects to contain version strings, but does not require
- systems to do anything with this information.
-
- * NON-ABI compliant executables will have a SGI_ONLY bit turned
- on in the .dynamic section. This flag will be understood and
- reported by elfdump. Only executables with this flag on will
- get the versioning treatment described below. This flag will
- be on by default.
-
- * When an executable is linked against a shared object, the last
- entry of the shared object's version string is recorded in the
- executable as part of the liblist. This can be examined by
- elfdump -Dl.
-
- * When an executable is linked, the user may specify -require_minor or
- -ignore_minor for each shared object linked against. If
- -require_minor is specified, a bit will be set in the flags field of
- the liblist entry for the shared object in question. The default
- is -ignore_minor.
-
- * When an executable (ABI or SGI_ONLY) is run rld will look
- for the proper filename in its usual search routine.
-
- * (SGI_ONLY) If a file with the correct name is found the
- version string in the liblist is compared to the list
- of version strings in the shared object. If the REQUIRE_MINOR bit
- is set in the liblist entry, and there is an exact match between the
- version string in the depender and one of the strings in the version
- list of the dependee, then that library is used. If the
-
- Page 19 Release 5.2
-
- DSO(5) Silicon Graphics DSO(5)
-
- REQUIRE_MINOR bit is clear, and if there is a match of major
- versions, then that library is used.
-
- * (SGI_ONLY) If no proper match is found, a new soname is built
- by taking the soname found in the executables liblist, and the
- major number found in the version string corresponding to that
- liblist entry, and putting them together as <soname>.<major>
- This is searched for in the same way as above. Version strings are
- matched in exactly the same way as described above.
-
- 30) Where can I find more documentation on DSO?
- Besides the other manpages mentioned below, System V Application Binary
- Interface and System V Application Binary Interface -- are both good
- sources of DSO implementation details.
-
-
-